﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace DotHandler
{
    public class Pilha<T> : Colecao<T>
    {
        #region Construtor
        public Pilha(uint size)
            : base(size)
        {
            this._index = new int[1];
            this._index[0] = -1;
        }
        #endregion

        #region Métodos
        public void Push(dynamic o, bool identity=true)
        {
            if (!this.IsFull())
            {
                _index[0] += 1;
                this._storage[_index[0]] = o;
                if (identity)
                {
                    o.Identity(this.identity);
                    this.identity +=  1;
                }
            }
            else
            {
                throw new NullReferenceException();
            }
        }

        public void Push(Boolean multiple, params dynamic[] o)
        {
            foreach (var item in o)
            {
                this.Push(item);
            }
        }

        public dynamic Pop()
        {
            if (!this.IsEmpty())
            {
                dynamic o = this._storage[this._index[0]];
                this._index[0] -= 1;
                return o;
            }
            throw new NullReferenceException();
        }

        public dynamic[] Pop(Boolean multiple, uint qtd)
        {
            if (qtd <= (this.Index + 1))
            {
                dynamic[] retorno = new dynamic[qtd];
                for (var i = 0; i < qtd; i += 1)
                {
                    retorno[i] = Pop();
                }
                return retorno;
            }
            throw new NullReferenceException();
        }

        public override Boolean IsFull()
        {
            return !(Index < Size - 1);
        }

        public override Boolean IsEmpty()
        {
            return (Index == -1);
        }
        
        public override void Destroy()
        {
            this._index[0] = -1;
            this._storage = new dynamic[Size];
        }

        public override int Index
        {
            get { return this._index[0]; }
        }

        public override void Each(Func<dynamic, bool> handler)
        {
            for (var i = 0; i <= this.Index; i += 1 )
            {
                if (handler((T)this._storage[i]) == false)
                {
                    break;
                };
            }
        }

        public new T Find(String property, String value)
        {
            value = value.ToLower();
            int i;
            for (i = 0; i <= _index[0]; i += 1)
            {
                var t = _storage[i].ToString(property);
                if (t == value)
                {
                    return _storage[i % Size];
                }
            }
            return default(T);
        }
        public new Lista<T> Find(bool multiple, String property, String value)
        {
            Lista<T> resultset = new Lista<T>((uint)this.Size);
            value = value.ToLower();
            int i;
            for (i = 0; i <= _index[0]; i += 1)
            {
                var t = _storage[i].ToString(property);
                if (t == value)
                {
                    resultset.Add(_storage[i]);
                }
            }
            return (resultset.Quantity > 0) ? resultset : null;
        }
        public override int Quantity
        {
            get { return this.Index + 1; }
        }
        #endregion

    }
}
